package com.fesine.learn.design.spi;

import java.util.ServiceLoader;

/**
 * @description: 类描述
 * @author: fesine
 * @createTime:2019/2/23
 * @update:修改内容
 * @author: fesine
 * @updateTime:2019/2/23
 *
 * spi的设计目标：
 * 面向对象的设计中，模块之间是基于接口编程，模块之间不对实现进行硬编码
 * 一旦代码里涉及到具体的实现类，就违反了可热插拔的原则，如果需要替换一种实现，就需要修改代码
 * 为了实现在模块装配时，不在模块里写死代码，这就需要一种服务实现机制。
 * java spi就是提供这样一种机制：
 * 为某接口寻找服务实现的机制。有点类似IOC的思想，就是装配的控制权移交到代码之外
 *
 * spi的具体约定如下：
 * 当服务的提供者（provider），提供了一个接口多种实现时，
 * 一般会在jar的META-INF/services/目录下，创建该接口的同名文件。
 * 该文件的内容就是该服务接口的具体实现类的名称
 * 而当外部加载这个文件的时候
 * 通过META-INF/services/目录里配置文件得到具体实现类，并加载实例化，完成该模块的装配。
 */
public class Test {
    public static void main(String[] args) {
        ServiceLoader<Command> serviceLoader = ServiceLoader.load(Command.class);
        for (Command command : serviceLoader) {
            command.execute();
        }
    }
}
